package api.db;

import api.*;
import api.utils.ExcelToMapUtils;
import api.utils.HttpClientUtils;
import api.utils.ParamsUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
public class ApiTestNgDb {

    public static final String dir = System.getProperty("user.dir") + File.separator + "data" + File.separator;
    public static final String filePath = dir + "apitest3.xlsx";

    public static final List<TestResult> allTestResult = new ArrayList<>();

    //map<String,List<TestStatistics>> 或者
    public static final List<TestStatistics> allTestStatistics = new ArrayList<>();

    public ExcelWriter excelWriter;


    @Test(dataProvider = "db", threadPoolSize = 50)
    public void testCaseNg(Map<String, Object> paramMap) {
        System.out.println(paramMap);
        String buniess=MapUtils.getString(paramMap,"business","");
        TestStatisticsDetail testStatistics = new TestStatisticsDetail();
        testStatistics.setBuniess(buniess);
        testStatistics.setScene(MapUtils.getString(paramMap, "scene", ""));
        String params=MapUtils.getString(paramMap,"params","");
        if (StringUtils.isNotBlank(params)&&JSON.isValidObject(params)) {
            Map map = JSON.parseObject(params, Map.class);
            paramMap.putAll(map);
        }
        paramMap.remove("params");
        List<TestResult> results = testCase(buniess, paramMap, testStatistics);
        allTestResult.addAll(results); //包含了所有业务组的

        testStatistics.setStatistics(ApiTest2.getStatisticsFormat(testStatistics));
        if (testStatistics.getError() > 0) {
            List<TestCase> testCases = testStatistics.getRetry();
            List<String> urlList = testCases.stream().map(TestCase::getUrl).
                    distinct().collect(Collectors.toList());
            testStatistics.setErrorApis(urlList.toString());
        }
        allTestStatistics.add(testStatistics);

        paramMap.clear();
        //统计处理 //重试
    }

    /**
     * @param buniess 业务
     * @param map 参数
     */
    public static List<TestResult> testCase(String buniess, Map<String,Object> map,TestStatistics testStatistics){

        List<TestCase> testCases  =ApiTestDb.getTestCase(buniess); //全部 -》业务关联 参数 过滤

        List<TestResult> results=new ArrayList<>();
        int order=1; //相对编号
        //testcase参数替换问题
        for (TestCase testCase : testCases) { //串行
            HttpResult httpResult = null;
            TestResult result=new TestResult();
            ApiTest2.replace(testCase,map);
            if("get".equals(testCase.getType())){
                httpResult = HttpClientUtils.doGet(testCase.getUrl(), testCase.getHeaders());
            }else if("post".equals(testCase.getType())){
                httpResult=HttpClientUtils.doPost(testCase.getUrl(),testCase.getParams(),testCase.getHeaders());
            }else if("postjson".equals(testCase.getType())){
                httpResult=HttpClientUtils.doPostJson(testCase.getUrl(),testCase.getParams(),testCase.getHeaders());
            }
            System.out.println(testCase+" "+httpResult);


            //检查点
            if(httpResult.getCode()==200){
                ApiTest2.addCheckPonit(order,httpResult.getMsg(),map,result);
            }

            if(httpResult.getCode()==200){
                testStatistics.setSuccess(testStatistics.getSuccess()+1);
            }else{
                testStatistics.setError(testStatistics.getError()+1);
                testStatistics.addRetry(testCase);
            }
            order++;
            //提取json结果
            if(httpResult.getCode()==200&&StringUtils.isNotBlank(testCase.getJsonCollect())){
                ParamsUtils.addJsonCollectToMap(testCase.getJsonCollect(),httpResult.getMsg(),map);
            }
            if(httpResult.getCode()==200&&StringUtils.isNotBlank(testCase.getRegxCollect())){
                ParamsUtils.addRegxCollectToMap(testCase.getRegxCollect(),httpResult.getMsg(),map);
            }
            result.setCode(httpResult.getCode());
            result.setHttpResult(httpResult.getMsg());
            result.setBuniess(buniess);
            try {
                BeanUtils.copyProperties(result,testCase);
            } catch (Exception e) {
                e.printStackTrace();
            }

            results.add(result);
        }
        log.info("业务{},参数{}执行完毕",buniess, map);
        // map.clear();
        return results;
    }



    @DataProvider(name = "db", parallel = true)
    public Iterator<Object[]> dbData() {
        List<Object[]> list = new ArrayList<>();
        ApiTestDb.getAllParams().forEach(map-> list.add(new Object[]{map}));
        return list.iterator();
    }

    @BeforeClass
    public void before() {
        SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM-dd(HH_mm)");
        String time = format0.format(System.currentTimeMillis());
        System.out.println(time);
        String resultPath = dir + "result_" + time + ".xlsx";
        excelWriter = EasyExcel.write(resultPath).build();
    }

    @AfterClass
    public void after() {
        //从数据库获取业务
        List<String> allBuniess = ApiTestDb.getAllbusiness();
        List<TestStatistics> allStatistics = new ArrayList<>();

        for (int i = 0; i < allBuniess.size(); i++) {
            String buniess = allBuniess.get(i);
            Collection<TestResult> testResults = allTestResult.stream().filter(test -> test.getBuniess().equals(buniess)).
                    collect(Collectors.toList());
            if (!testResults.isEmpty()) {
                WriteSheet writeSheet = EasyExcel.writerSheet(i, buniess).head(TestResultEasyExcel.class).build();
                excelWriter.write(testResults, writeSheet);
            }

            //汇总每一组的统计结果
            List<TestStatistics> buniessDetailStatistics = allTestStatistics.stream().filter(test -> test.getBuniess().
                    equals(buniess)).collect(Collectors.toList());
            TestStatistics buniessStatistics =new TestStatistics();
            buniessStatistics.setBuniess(buniess);
            for (int j = 0; j < buniessDetailStatistics.size(); j++) {
                TestStatistics statistics = buniessDetailStatistics.get(j);
                buniessStatistics.setSuccess(statistics.getSuccess()+buniessStatistics.getSuccess());
                buniessStatistics.setError(statistics.getError()+buniessStatistics.getError());
                buniessStatistics.getRetry().addAll(statistics.getRetry());
            }
            buniessStatistics.setStatistics(ApiTest2.getStatisticsFormat(buniessStatistics));
            if (buniessStatistics.getError() > 0) {
                List<TestCase> testCases = buniessStatistics.getRetry();
                List<String> urlList = testCases.stream().map(TestCase::getUrl).
                        distinct().collect(Collectors.toList());
                buniessStatistics.setErrorApis(urlList.toString());
            }

            allStatistics.add(buniessStatistics);

        }

        WriteSheet writeSheet = EasyExcel.writerSheet("统计").head(TestStatistics.class).build();
        //allStatistics.sort(Comparator.comparing(TestStatistics::getBuniess));
        excelWriter.write(allStatistics, writeSheet);

        ApiTest2.retry(allStatistics,excelWriter);
        excelWriter.finish();  //close
    }


}
